/*
COPYRIGHT (C) 2008 EPISERVER AB

THIS FILE IS PART OF SCRUM DASHBOARD.

SCRUM DASHBOARD IS FREE SOFTWARE: YOU CAN REDISTRIBUTE IT AND/OR MODIFY IT UNDER THE TERMS OF 
THE GNU LESSER GENERAL PUBLIC LICENSE VERSION v2.1 AS PUBLISHED BY THE FREE SOFTWARE FOUNDATION.

SCRUM DASHBOARD IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT WITHOUT ANY WARRANTY; WITHOUT
EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU LESSER
GENERAL PUBLIC LICENSE FOR MORE DETAILS.

YOU SHOULD HAVE RECEIVED A COPY OF THE GNU LESSER GENERAL PUBLIC LICENSE ALONG WITH SCRUM DASHBOARD. 
IF NOT, SEE <HTTP://WWW.GNU.ORG/LICENSES/>.
*/
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using ScrumDashboard.Library;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using System.Collections.Generic;
using System.Linq;
using ScrumDashboard.Library.Model;
using ScrumDashboard.Library.Tfs;

namespace ScrumDashboard
{
    public partial class _Default : System.Web.UI.Page
    {
        SprintViewData _model;
        private TfsManager _tfs = new TfsManager();

        public SprintViewData ViewData
        {
            get { return _model; }
        }

        public string CurrentProject
        {
            get { return project.SelectedValue; }
        }

        public string CurrentTeam
        {
            get { return teamList.SelectedValue; }
        }

        public int CurrentSprint
        {
            get { return Int32.Parse(sprintList.SelectedValue); }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if(IsPostBack)
            {
                _model = _tfs.GetSprintViewData(project.SelectedValue,Int32.Parse(sprintList.SelectedValue),teamList.SelectedValue);
            }
            else
            {
                Page.ClientScript.RegisterStartupScript(typeof(_Default), "tfsWebAccessRelative", "<script type=\"text/javascript\">var tfsWebAccessRelative = '" + ConfigurationManager.AppSettings["tfsWebAccessRelative"] + "';</script>");
                Page.ClientScript.RegisterStartupScript(typeof(_Default), "viewSprintButton", "var viewSprintButtonID = '" + viewSprintButton.ClientID + "';", true);


                if (ConfigurationManager.AppSettings["tfsKeepAlive"] == null || Boolean.Parse(ConfigurationManager.AppSettings["tfsKeepAlive"]))
                {
                    Page.ClientScript.RegisterStartupScript(typeof(_Default), "tfsKeepAlive", "setInterval(TfsKeepAlive, 20*60*1000);", true);
                    tfsKeepAliveFrameID.Visible = true;
                }

                Project[] projects = _tfs.GetScrumProjects();
                if (projects.Length > 0)
                {
                    foreach (Project p in projects)
                    {
                        project.Items.Add(new ListItem(p.Name, p.Name));
                        if (Request.Cookies["LastViewedProject"] != null && Request.Cookies["LastViewedProject"].Value == p.Name)
                            project.SelectedIndex = project.Items.Count - 1;
                    }

                    if (project.Items.Count > 0 && project.SelectedIndex < 0)
                        sprintList.SelectedIndex = 0;

                    if (project.SelectedIndex >= 0)
                    {
                        PopulateProjectInfo();

                        ViewSprintClick(this, EventArgs.Empty);
                    }
                }
                else
                {
                    ClientScript.RegisterStartupScript(typeof(_Default),"ProjectError","<script type=\"text/javascript\">alert('Error: No Scrum projects where found in Team Foundation Server')</script>");
                }
            }
        }

        protected string GetVersion()
        {
            return System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
        }

        protected string RenderGoal()
        {
            string goal = String.IsNullOrEmpty(ViewData.Sprint.Goal) ? "No goal defined" : ViewData.Sprint.Goal;
            if (goal.Length > 130)
            {
                return "<span id=\"goalText\">" + Server.HtmlEncode(goal.Substring(0, 130)) + " <a href=\"#\" onclick=\"ExpandGoal()\">[More..]</a></span><input id=\"goalHidden\" name=\"goalHidden\" type=\"hidden\" value=\"" + Server.HtmlEncode(goal) + "\" />";
            }

            return goal;
        }

        private void PopulateProjectInfo()
        {
            sprintList.Items.Clear();
            foreach (SprintItem si in _tfs.GetSprints(project.SelectedValue))
            {
                sprintList.Items.Add(new ListItem(si.Title, si.SprintNumber.ToString()));
                if (Request.Cookies["LastViewedSprint"] != null && Request.Cookies["LastViewedSprint"].Value == si.SprintNumber.ToString())
                    sprintList.SelectedIndex = sprintList.Items.Count - 1;
            }

            if (sprintList.Items.Count > 0 && sprintList.SelectedIndex < 0)
                sprintList.SelectedIndex = 0;


            teamList.Items.Clear();
            teamList.Items.Add(new ListItem("<all>", ""));
            foreach (string teamName in _tfs.GetScrumTeams(project.SelectedValue))
            {
                teamList.Items.Add(new ListItem(teamName, teamName));
                if (Request.Cookies["LastViewedTeam"] != null && Request.Cookies["LastViewedTeam"].Value == teamName)
                    teamList.SelectedIndex = teamList.Items.Count - 1;
            }

            if (teamList.Items.Count > 0 && teamList.SelectedIndex < 0)
                teamList.SelectedIndex = 0;
        }

        protected void ProjectChanged(object sender, EventArgs e)
        {
            PopulateProjectInfo();
            ViewSprintClick(this, EventArgs.Empty);
        }

        protected string GetWorkItemCssClass(object o)
        {
            SprintBacklogItem sbi = (SprintBacklogItem)o;

            if (sbi.IsUnplanned(ViewData.Sprint.SprintStart))
                return "ItemUnplanned";

            switch (sbi.State)
            {
                case "Done":
                    return "ItemDone";
                case "Not Done":
                    return "ItemNotDone";
                case "In Progress":
                    return "ItemInProgress";
                case "Ready For Test":
                    return "ItemReadyForTest";
            }

            return "";
        }

        public void Update()
        {
            ImagePanel.Update();
            WorkItemPanel.Update();
            sprintTotalPanel.Update();
            ViewSprintClick(this, EventArgs.Empty);
        }

        protected void ViewSprintClick(object sender, EventArgs e)
        {
            int sprintNumber = Int32.Parse(sprintList.SelectedValue);
            
            _model = _tfs.GetSprintViewData(project.SelectedValue,Int32.Parse(sprintList.SelectedValue),teamList.SelectedValue);

            bool tfsMoveDoneToBottom = String.IsNullOrEmpty(ConfigurationManager.AppSettings["tfsMoveDoneToBottom"]) ? true : Boolean.Parse(ConfigurationManager.AppSettings["tfsMoveDoneToBottom"]);
            if (!tfsMoveDoneToBottom)
            {
                productBacklog.DataSource = _model.ProductBacklog;
            }
            else
            {
                var notDoneYet = from i in _model.ProductBacklog where i.State != "Done" orderby i.BusinessPriority descending, i.DeliveryOrder descending select i;
                var done = from i in _model.ProductBacklog where i.State == "Done" orderby i.BusinessPriority descending, i.DeliveryOrder descending select i;
                productBacklog.DataSource = notDoneYet.Concat(done);
            }
            
            Response.Cookies["LastViewedSprint"].Value = sprintList.SelectedValue;
            Response.Cookies["LastViewedSprint"].Expires = DateTime.Now.AddDays(30);
            Response.Cookies["LastViewedTeam"].Value = teamList.SelectedValue;
            Response.Cookies["LastViewedTeam"].Expires = DateTime.Now.AddDays(30);
            Response.Cookies["LastViewedProject"].Value = project.SelectedValue;
            Response.Cookies["LastViewedProject"].Expires = DateTime.Now.AddDays(30);

            string imageID = ConfigurationManager.AppSettings["tfsReportImageID"];
            if (String.IsNullOrEmpty(imageID))
            {
                imageID = "C_12_S";
            }

            string baseReportUrl = ConfigurationManager.AppSettings["tfsReportServer"] + "?" + Server.UrlEncode("/" + project.SelectedValue + "/Sprint Burndown Chart") + "&rs:Command={0}&rs:Format=HTML4.0&rs:ClearSession=true&vReleasePath=" + Server.UrlEncode("\\" + project.SelectedValue + sprintList.SelectedItem.Text);
            if (teamList.SelectedValue.Length > 0)
            {
                baseReportUrl += "&vTeamName=" + teamList.SelectedValue;
            }
            reportViewer.Attributes["src"] = String.Format(baseReportUrl, "RenderStream");
            reportViewer.Visible = true;
            reportViewer.Attributes["onload"] = String.Format("$get('burnDownChartLink').href='{0}';$get('burnDownChart').src='{1}&rs:ImageID={2}'", String.Format(baseReportUrl, "Render"), String.Format(baseReportUrl, "RenderStream"), imageID);

            DataBind();
        }

        protected IEnumerable<SprintBacklogItem> GetStatus(object id, string status)
        {
            int intId = (int)id;

            if (status != "Not Done")
            {
                return from i in ViewData.SprintBacklog
                        where i.State == status && i.ProductBackLogId == intId
                        orderby i.Changed descending
                        select i;
            }
            else
            {
                return from i in ViewData.SprintBacklog
                        where i.State == status && i.ProductBackLogId == intId
                        select i;
            }
        }
    }
}
